package com.zoho.daliansheng.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zoho.daliansheng.common.U8SystemRecord;
import com.zoho.daliansheng.common.ZohoRecord;
import com.zoho.daliansheng.config.CRMPathConfig;
import com.zoho.daliansheng.config.DatasourceEnum;
import com.zoho.daliansheng.config.U8SystemPathConfig;
import com.zoho.daliansheng.dlcr.ApiReturnInfo;
import com.zoho.daliansheng.dlcr.DlcrU8WebService;
import com.zoho.daliansheng.dlcr.DlcrU8WebServiceSoap;
import com.zoho.daliansheng.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Service
public class SaleOrderServiceImpl implements SaleOrderService {

    ZohoRecord zohoRecord;

    U8SystemRecord u8SystemRecord;

    U8SystemPathConfig u8SystemPathConfig;

    CRMPathConfig crmPathConfig;

    AccountService accountService;

    public SaleOrderServiceImpl(ZohoRecord zohoRecord, U8SystemRecord u8SystemRecord, U8SystemPathConfig u8SystemPathConfig, CRMPathConfig crmPathConfig, AccountService accountService) {
        this.zohoRecord = zohoRecord;
        this.u8SystemRecord = u8SystemRecord;
        this.u8SystemPathConfig = u8SystemPathConfig;
        this.crmPathConfig = crmPathConfig;
        this.accountService = accountService;
    }

    @Override
    public ResultUtil<Object> pushSaleOrderToERP(JSONObject json) {
        log.info("pushSaleOrderToERP,parameter={}", json.toJSONString());

        String saleOrderId = json.getString("saleOrderId");
        if (StringUtils.isBlank(saleOrderId)) {
            return ResultUtil.error("saleOrderId为空");

        }
        // 1 获取CRM数据
        JSONObject saleOrderData = CrmApiUtil.getDataById(zohoRecord.getAccessToken(), crmPathConfig.getGetSaleOrderModuleName(), saleOrderId);
        if (Objects.isNull(saleOrderData)) {
            return ResultUtil.error("saleOrderId数据为空");
        }

        String khCompany = saleOrderData.getString("KHCompany");
        String webServiceUrl = U8SystemApiUtil.getWebUrlByCompanyName(khCompany);
        if (StringUtils.isBlank(webServiceUrl)) {
            return ResultUtil.error("客户所属公司数据有误");
        }

        // 2 映射字段
        JSONObject filterData = filerData(saleOrderData, khCompany);

        String approvalState = saleOrderData.getString("approvalstate"); // 审批状态
        if (!"批准".equals(approvalState)) {
            String errMsg = "单据未经审批，不允许推送。";
            JSONObject updateData = new JSONObject();
            updateData.put("id", saleOrderId);
            updateData.put("push_status", "失败");
            updateData.put("fail_reason", errMsg);
            List<JSONObject> list = new ArrayList<>();
            list.add(updateData);
            CrmApiUtil.batchUpdateDataByList(zohoRecord.getAccessToken(), list, crmPathConfig.getGetSaleOrderModuleName());
            return ResultUtil.error(errMsg);
        }

        try {
            // 先删除erp数据
            ResultUtil<Object> delResult = deleteSaleOrder(json);
            if (delResult.getCode() != 200 && (delResult.getMessage().startsWith("03") || delResult.getMessage().startsWith("04"))) {
                return delResult;
            }

            // 3 推送ERP
            log.info("推送erp销售订单接口parameter={}", filterData.toJSONString());
            DlcrU8WebService webService = new DlcrU8WebService(new URL(webServiceUrl));
            DlcrU8WebServiceSoap api = webService.getDlcrU8WebServiceSoap();
            String reviewDate = saleOrderData.getString("ReviewDate"); // 审核日期
            ApiReturnInfo apiReturnInfo = api.saveSaleOrderInfoEx(filterData.toJSONString(),reviewDate, approvalState.equals("批准"));
            log.info("推送erp销售订单接口result={}", JSONObject.toJSONString(apiReturnInfo));
            if (apiReturnInfo.isIsSuccess()) {

                log.info("成功推送销售订单，{}", saleOrderId);
                String billNum = apiReturnInfo.getBillNum();

                JSONObject updateData = new JSONObject();
                updateData.put("id", saleOrderId);
                updateData.put("push_status", "成功");
                updateData.put("fail_reason", "");
                updateData.put("ERP_Number", billNum);
                updateData.put("push_parameter", filterData.toJSONString());
                List<JSONObject> list = new ArrayList<>();
                list.add(updateData);
                CrmApiUtil.batchUpdateDataByList(zohoRecord.getAccessToken(), list, crmPathConfig.getGetSaleOrderModuleName());

                return ResultUtil.success();
            } else {
                log.info("推送销售订单失败，{}", saleOrderId);
                String errMsg = apiReturnInfo.getErrMsg();

                JSONObject updateData = new JSONObject();
                updateData.put("id", saleOrderId);
                updateData.put("push_status", "失败");
                updateData.put("fail_reason", errMsg);
                updateData.put("push_parameter", filterData.toJSONString());
                List<JSONObject> list = new ArrayList<>();
                list.add(updateData);
                CrmApiUtil.batchUpdateDataByList(zohoRecord.getAccessToken(), list, crmPathConfig.getGetSaleOrderModuleName());

                return ResultUtil.error(errMsg);
            }

        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

        return ResultUtil.success();

    }

    @Override
    public ResultUtil<Object> deleteSaleOrder(JSONObject json) {
        log.info("deleteSaleOrder,parameter={}", json.toJSONString());

        String saleOrderId = json.getString("saleOrderId");
        if (StringUtils.isBlank(saleOrderId)) {
            return ResultUtil.error("saleOrderId为空");

        }
        // 1 获取CRM数据
        JSONObject saleOrderData = CrmApiUtil.getDataById(zohoRecord.getAccessToken(), crmPathConfig.getGetSaleOrderModuleName(), saleOrderId);
        if (Objects.isNull(saleOrderData)) {
            return ResultUtil.error("saleOrderId数据为空");
        }

        String khCompany = saleOrderData.getString("KHCompany");
        String webServiceUrl = U8SystemApiUtil.getWebUrlByCompanyName(khCompany);
        if (StringUtils.isBlank(webServiceUrl)) {
            return ResultUtil.error("客户所属公司数据有误");
        }

        // 2 调用erp接口
        String erpNumber = saleOrderData.getString("ERP_Number");
        if (StringUtils.isNotBlank(erpNumber)) {

            log.info("删除erp销售订单接口parameter={}", erpNumber);
            try {
                DlcrU8WebService webService = new DlcrU8WebService(new URL(webServiceUrl));
                DlcrU8WebServiceSoap api = webService.getDlcrU8WebServiceSoap();
                ApiReturnInfo apiReturnInfo = api.delSaleOrderInfo(erpNumber);
                //log.info("删除erp销售订单接口result={}", JSONObject.toJSONString(apiReturnInfo));
                if (apiReturnInfo.isIsSuccess()) {
                    log.info("成功删除erp销售订单");
                    return ResultUtil.success();
                } else {

                    JSONObject updateData = new JSONObject();
                    updateData.put("id", saleOrderId);
                    updateData.put("fail_reason", apiReturnInfo.getErrMsg());
                    List<JSONObject> list = new ArrayList<>();
                    list.add(updateData);
                    CrmApiUtil.batchUpdateDataByList(zohoRecord.getAccessToken(), list, crmPathConfig.getGetSaleOrderModuleName());
                    log.info("删除erp销售订单失败，{}", apiReturnInfo.getErrMsg());
                    return ResultUtil.error(apiReturnInfo.getErrMsg());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        } else {
            return ResultUtil.error("该销售订单未推送到ERP，无法删除");
        }

        return ResultUtil.success();
    }

    private JSONObject filerData(JSONObject saleOrderData, String company) {

        //System.out.println("saleOrderData.toJSONString() = " + saleOrderData.toJSONString());
        JSONObject result = new JSONObject();
        JSONObject header = new JSONObject();
        header.put("bdisflag", false); // 是否整单打折
        header.put("breturnflag", false); // 退货标志（1-退货；0-正常）
        //header.put("caddcode", saleOrderData.getString("ShippingAddressnew")); // 发货地址编码
        header.put("cbustype", saleOrderData.getString("BusinessType")); // 业务类型

        JSONObject contact = saleOrderData.getJSONObject("Contact_Name");
        if (Objects.nonNull(contact)) {
            header.put("ccontactname", contact.getString("name")); // 联系人姓名
        }

        String accountName = "";
        JSONObject account = saleOrderData.getJSONObject("Account_Name");
        if (Objects.nonNull(account)) {

            // 重新推送客户数据
            String accountId = account.getString("id");
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("accountId", accountId);
            accountService.pushAccountToERP(jsonObject);

            header.put("ccusname", account.getString("name")); // 客户名称
            accountName = account.getString("name");
            JSONObject accountData = CrmApiUtil.getDataById(zohoRecord.getAccessToken(), crmPathConfig.getAccountModuleName(), account.getString("id"));
            if (Objects.nonNull(accountData)) {
                header.put("ccuscode", accountData.getString("ERP_account_num")); // 客户编码
            }
        }

        String shippingAddressnew = saleOrderData.getString("ShippingAddressnew"); // 发货地址
        if (StringUtils.isNotBlank(shippingAddressnew)) {
            header.put("ccusoaddress", shippingAddressnew); // 发货地址
        }
        String address = ""; // 送货 、 收货地址
        JSONObject ShouHuoAddress = saleOrderData.getJSONObject("AddressLibraryNumber"); // 收货地址，跟发货地址是同一字段
        if (Objects.nonNull(ShouHuoAddress)) {
            String id = ShouHuoAddress.getString("id");
            JSONObject dataById = CrmApiUtil.getDataById(zohoRecord.getAccessToken(), crmPathConfig.getAddressModuleName(), id);
            if (Objects.nonNull(dataById)) {

                String sheng = dataById.getString("Sheng");// 省
                String Shi = dataById.getString("Shi");// 市
                String AddressDizhiku = dataById.getString("AddressDizhiku");// 详细地址
                address = sheng + Shi + AddressDizhiku;
                header.put("ccusoaddress", sheng + Shi + AddressDizhiku); // 收货地址
                header.put("caddcode", dataById.getString("Name")); // 收货地址编码

            }

        }

        String departCode = ""; // 部门编码，从业务员取
        JSONObject salesman = saleOrderData.getJSONObject("Salesman");
        if (Objects.nonNull(salesman)) {
            String userId = salesman.getString("id");
            Map<String, String> data = CrmApiUtil.getUserCodeByCompany(zohoRecord.getAccessToken(), userId, company);
            header.put("cpersoncode", data.get("personCode")); // 业务员编码
            header.put("cdepcode", data.get("departCode")); // 部门编码
            departCode = data.get("departCode");
        }

        header.put("ccusperson", saleOrderData.getString("account_contact")); // 客户联系人
        //header.put("ccuspersoncode", saleOrderData.getString("account_num")); // 联系人编码
        header.put("cexch_name", saleOrderData.getString("BiZhong")); // 币种名称
        //header.put("cinvoicecompany", saleOrderData.getString("account_num")); // 开票单位编码

        String erpContact = "";
        if (StringUtils.isNotBlank(saleOrderData.getString("ShouhuoContact"))) {
            erpContact = saleOrderData.getString("ShouhuoContact");
        }
        if (StringUtils.isNotBlank(saleOrderData.getString("ShouhuoPhoneNew"))) {
            erpContact += saleOrderData.getString("ShouhuoPhoneNew");
        }

        String payWay = saleOrderData.getString("pay_way");
        String transferWay = saleOrderData.getString("transfer_way");
        if (company.equals(DatasourceEnum.GONG_CHANG.getCompanyName())) {
            header.put("chdefine8", payWay); // 付款方式
            header.put("chdefine7", transferWay); // 运输方式和费用负担
            String settlementMethod = saleOrderData.getString("SettlementMethod");
            if (StringUtils.isNotBlank(settlementMethod)) {
                header.put("csscode", settlementMethod.substring(0, settlementMethod.indexOf("-"))); // 结算方式
            }
            header.put("cmemo", saleOrderData.getString("PaymentTerms")); // 收款条件
        } else if (company.equals(DatasourceEnum.SU_ZHOU.getCompanyName())) {
            header.put("chdefine28", payWay); // 付款方式
            header.put("chdefine27", transferWay); // 运输方式和费用负担
            header.put("chdefine4", saleOrderData.getString("pay_terms")); // 付款条件
            header.put("cmemo", saleOrderData.getString("Remark")); // 备注
            header.put("cdefine2", saleOrderData.getString("area")); // 区域
        } else if (company.equals(DatasourceEnum.CHANG_ZHOU.getCompanyName())) {
            header.put("chdefine40", payWay); // 付款方式
            header.put("chdefine39", transferWay); // 运输方式和费用负担
            header.put("chdefine20", accountName); // 客户（上面的客户）
            header.put("chdefine17", erpContact); // 客户联系人（收货联系人）
            header.put("chdefine8", address); // 送货地址（ 收货地址）
            header.put("chdefine4", saleOrderData.getString("pay_terms")); // 付款条件
            header.put("chdefine5", saleOrderData.getString("Remark")); // 备注
            header.put("cdefine11", saleOrderData.getString("ShippingRequirements")); // 特殊发货要求
        } else if (company.equals(DatasourceEnum.DA_LIAN.getCompanyName())) {
            header.put("chdefine63", payWay); // 付款方式
            header.put("chdefine62", transferWay); // 运输方式和费用负担
            header.put("chdefine20", accountName); // 客户（上面的客户）
            header.put("chdefine17", erpContact); // 客户联系人（收货联系人）
            header.put("chdefine8", address); // 送货地址（ 收货地址）
            header.put("chdefine5", saleOrderData.getString("Remark")); // 备注
            header.put("cdefine11", saleOrderData.getString("ShippingRequirements")); // 特殊发货要求
            header.put("chdefine4", saleOrderData.getString("pay_terms")); // 付款条件
            header.put("chdefine25", saleOrderData.getString("SalesDepartment")); // 销售部门
            header.put("chdefine51", departCode); // 销售部门编码
            header.put("chdefine23", saleOrderData.getString("NY_code")); // 南亚客户编号
            header.put("chdefine18", saleOrderData.getString("NY_customer_name")); // 南亚建档客户名称
            header.put("chdefine22", saleOrderData.getString("area")); // 区域
            if (Objects.nonNull(salesman)) {
                header.put("chdefine24", salesman.getString("name")); // 销售业务员
            }
            //header.put("caddcode", saleOrderData.getString("ShouHuoAddressCode")); // 收货地址编码

        } else if (company.equals(DatasourceEnum.XIN_CAI_LIAO.getCompanyName())) {
            header.put("chdefine63", payWay); // 付款方式
            header.put("chdefine62", transferWay); // 运输方式和费用负担
            header.put("chdefine4", saleOrderData.getString("pay_terms")); // 付款条件
            header.put("chdefine22", saleOrderData.getString("area")); // 区域
            header.put("cdefine11", saleOrderData.getString("ShippingRequirements")); // 特殊发货要求
            header.put("chdefine5", saleOrderData.getString("Remark")); // 备注
            header.put("chdefine17", erpContact); // 客户联系人（收货联系人）
            header.put("chdefine8", address); // 送货地址（ 收货地址）
            header.put("chdefine25", saleOrderData.getString("SalesDepartment")); // 销售部门
            header.put("chdefine51", departCode); // 销售部门编码
            header.put("chdefine20", accountName); // 客户（上面的客户）
            if (Objects.nonNull(salesman)) {
                header.put("chdefine24", salesman.getString("name")); // 销售业务员
            }

        }


        header.put("ccontactname", erpContact); // 收货联系人 + 收货联系人手机

        JSONObject owner = saleOrderData.getJSONObject("Owner");
        if (Objects.nonNull(owner)) {
            //String ownerId = owner.getString("id");
            //Map<String, String> data = CrmApiUtil.getUserCodeByCompany(zohoRecord.getAccessToken(), ownerId, company);
            header.put("cmaker", owner.get("name")); // 专营业务员编码
        }
        header.put("cmobilephone", saleOrderData.getString("ShouhuoPhoneNew")); // 联系人手机


        header.put("csocode", saleOrderData.getString("CRM_Number")); // 销售订单号
        String salesType = saleOrderData.getString("SalesType");
        if ("库存销售".equals(salesType)) {
            header.put("cstcode", "01"); // 销售类型编码
        } else if ("直发销售".equals(salesType)) {
            header.put("cstcode", "02"); // 销售类型编码
        }
        header.put("ddate", saleOrderData.getString("OrderDate")); // 单据日期
        header.put("dpredatebt", saleOrderData.getString("OrderDate")); // 预发货日期
        header.put("dpremodatebt", saleOrderData.getString("OrderDate")); // 预完工日期
        header.put("id", 0); // 表头ID 系统自动生成
        header.put("iexchrate", saleOrderData.getString("HuiLv")); // 汇率
        header.put("istatus", 0); // 状态（0-未审核；1-已审核）
        header.put("itaxrate", saleOrderData.getString("ShuiLv")); // 表头税率
        header.put("ivtid", 95); // 固定 95 单据模版号


        String shippingMethod = saleOrderData.getString("ShippingMethod"); // 发运方式
        if (StringUtils.isNotBlank(shippingMethod)) {
            header.put("csccode", shippingMethod.substring(0, shippingMethod.indexOf("-"))); // 发运方式编码
        }


        JSONObject zhuli = saleOrderData.getJSONObject("zhuli"); // 助理
        if (Objects.nonNull(zhuli)) {
            if (company.equals(DatasourceEnum.SU_ZHOU.getCompanyName())) {
                header.put("cdefine1", zhuli.get("name")); // 表头自定义项1
            } else if (company.equals(DatasourceEnum.DA_LIAN.getCompanyName())) {
                header.put("chdefine26", zhuli.get("name")); // 表头扩展自定义项26
            } else if (company.equals(DatasourceEnum.XIN_CAI_LIAO.getCompanyName())) {
                header.put("chdefine26", zhuli.get("name")); // 表头扩展自定义项26
            }
        }

        result.put("Head", header);

        // 明细行数据
        List<JSONObject> bodyList = new ArrayList<>();
        JSONArray orderedItems = saleOrderData.getJSONArray("Ordered_Items");
        if (Objects.nonNull(orderedItems)) {
            List<JSONObject> detailList = orderedItems.toJavaList(JSONObject.class);
            int index = 1;
            for (JSONObject detail : detailList) {
                JSONObject body = new JSONObject();
                body.put("autoid", 0); // autoid 表体主键,系统自动生成 无需传值,可以给0
                body.put("id", 0); // id 表头ID 系统自动生成 无需传值,可以给0


                if (company.equals(DatasourceEnum.GONG_CHANG.getCompanyName())) { // 工厂的存货编码，需要再转回去

                    List<String> filedList = getCrmFieldUtil.getGongchangTranferFieldList();
                    List<JSONObject> transferList = CrmApiUtil.getModuleData(zohoRecord.getAccessToken(), crmPathConfig.getGongChangTransferModuleName(), filedList);

                    List<JSONObject> collect = transferList.stream().filter(object -> object.getString("crm_code").equals(detail.getString("Product_Code"))).collect(Collectors.toList());
                    if (collect.size() > 0) {
                        JSONObject jsonObject = collect.get(0);
                        body.put("cinvcode", jsonObject.getString("Name")); // 存货编码
                    }

                } else {
                    body.put("cinvcode", detail.getString("Product_Code")); // 存货编码
                }


                JSONObject product_name = detail.getJSONObject("Product_Name"); // 产品名称
                if (Objects.nonNull(product_name)) {
                    String id = product_name.getString("id");
                    JSONObject dataById = CrmApiUtil.getDataById(zohoRecord.getAccessToken(), crmPathConfig.getProductModuleName(), id);
                    if (Objects.nonNull(dataById)) {
                        body.put("cunitid", dataById.getString("SalesDefaultUnitOfMeasurementCode")); // 计量单位编码
                        body.put("cgroupcode", dataById.getString("UnitOfMeasurementGroupCode")); // 计量单位组编码
                        body.put("igrouptype", dataById.getString("igrouptype")); // 是否多计量
                    }
                }

                body.put("dPreDate",saleOrderData.getString("OrderDate")); // 预计发货日期,取CRM订单的主表【订单日期】字段的内容
                body.put("iquantity", detail.getString("dun")); // 数量,必须填写不能为0

                body.put("inum", detail.getString("SalesQty")); // 辅计量数量 、件数
                body.put("iquotedprice", detail.getString("UnitPriceIncludingTax")); // 报价,必须填写,不能为0
                body.put("itaxunitprice", detail.getString("UnitPriceIncludingTax")); // 原币含税单价
                body.put("iunitprice", detail.getString("UnitPriceWithoutTax")); // 原币无税单价
                body.put("imoney", detail.getString("TaxfreeAmount")); // 原币无税金额
                body.put("itax", detail.getString("TaxAmount")); // 原币税额
                body.put("isum", detail.getString("Total_price_and_tax")); // 原币价税合计
                body.put("inatunitprice", detail.getString("UnitPriceWithoutTax")); // 本币无税单价
                //body.put("inatmoney", detail.getString("TaxfreeAmount")); // 本币无税金额
                //body.put("inattax", detail.getString("account_num")); // 本币税额
                //body.put("inatsum", detail.getString("account_num")); // 本币价税合计
                //body.put("inatdiscount", detail.getString("account_num")); // 本币折扣额
                //body.put("idiscount", detail.getString("account_num")); // 原币折扣额
                body.put("dpredate", detail.getString("EstimatedDeliveryDate")); // 预发货日期
                body.put("iinvexchrate", detail.getString("changerate")); // 换算率
                body.put("itaxrate", detail.getString("TaxRate")); // 税率
                //body.put("kl", detail.getString("account_num")); // 扣率 必须填写 100代表无折扣
                //body.put("kl2", detail.getString("account_num")); // 二次扣率
                body.put("irowno", index++); // 行号,从1开始赋值
                body.put("dpremodate", saleOrderData.getString("OrderDate")); // 预完工日期
                body.put("bsaleprice", 1); // 报价含税标识
                //body.put("dreleasedate", detail.getString("account_num")); // 释放日期
                //body.put("bgift", detail.getString("account_num")); // 赠品标识
                //body.put("editprop", detail.getString("account_num")); // 该字段保存单据时使用,查询时无用


                if (company.equals(DatasourceEnum.GONG_CHANG.getCompanyName())) {

                } else if (company.equals(DatasourceEnum.SU_ZHOU.getCompanyName())) {
                    body.put("cdefine1", detail.getString("MnemonicCode")); // 助记号
                    body.put("cdefine29", detail.getString("CommonName")); // 通用名称
                    body.put("cdefine30", detail.getString("ShengChanQiye")); // 生产企业
                } else if (company.equals(DatasourceEnum.CHANG_ZHOU.getCompanyName())) {
                    body.put("free1", detail.getString("NetWeight")); // 净重
                    body.put("cdefine25", saleOrderData.getString("ShouHuoAddress")); // 客户联系人电话
                    body.put("cdefine30", saleOrderData.getString("ShouhuoContact")); // 客户收货地址

                } else if (company.equals(DatasourceEnum.DA_LIAN.getCompanyName())) {

                } else if (company.equals(DatasourceEnum.XIN_CAI_LIAO.getCompanyName())) {
                }

                bodyList.add(body);
            }
        }
        result.put("Bodys", bodyList);
        return result;
    }

}
